package microcredit.gui.handler;

import java.awt.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import microcredit.gui.editor.AbstractEditorForm;
import microcredit.gui.editor.EditorPanel;
import microcredit.gui.editor.loan.LoanGeneralForm;
import microcredit.gui.editor.loan.LoanHistoryForm;
import microcredit.gui.util.ReportWorker;
import microcredit.model.Member;
import microcredit.model.MemberToLoan;
import microcredit.model.Report;
import microcredit.model.ValidationException;
import microcredit.model.bo.BOLoan;
import microcredit.model.bo.BOReport;
import microcredit.model.domain.Status;

public class MemberToLoanHandler extends AbstractHandler<MemberToLoan> {

	@Override
	public void delete(MemberToLoan e) throws Throwable {
		BOLoan.create().delete(e);
	}
	
	@Override
	public void print(MemberToLoan e) throws Exception {
		if (e.getMember() == null
				|| e.getSequenceID() == null) {
			throw new ValidationException("The loan must be saved before printing. Please save the loan first.");
		}
		
		List<Report> reports = BOReport.create().getReports();
		Report loanForm = null;
		for (Report report : reports) {
			if (report.getName().equalsIgnoreCase("Loan form")) {
				loanForm = report;
				break;
			}
		}
		if (loanForm != null) {
			Map<String, Object> parameters = new HashMap<String, Object>();
			
			Long memberID = e.getMemberID();
			if (e.getMember() != null && memberID == null) {
				memberID = e.getMember().getId();
			}
			parameters.put("MEMBER_ID",memberID); // member id
			parameters.put("LOAN_ID", e.getSequenceID()); // add loan sequence id
			
			ReportWorker worker = new ReportWorker(loanForm, parameters);
			worker.run();
			
		} else {
			throw new ValidationException("Loan form report not found in reports directory.");
		}
	}
	
	@Override
	public MemberToLoan save(MemberToLoan entity) throws Throwable {
		return BOLoan.create().save(entity.getMember(), entity);
	}
	
	@Override
	public MemberToLoan refresh(MemberToLoan element) throws Throwable {
		return BOLoan.create().refresh(element);
	}
	
	@Override
	public MemberToLoan newEntity(Component parent) throws Throwable {
		if (getAssociatedMember() == null || getAssociatedMember().getId() == null) {
			throw new ValidationException("Please save the member before creating loans!");
		} else if (getAssociatedMember().getStatus() != Status.A) {
			throw new ValidationException("The member must be active to create new loans!");
		}
		
		List<AbstractEditorForm<MemberToLoan>> forms = new ArrayList<AbstractEditorForm<MemberToLoan>>();
		forms.add(new LoanGeneralForm());
		forms.add(new LoanHistoryForm());
		MemberToLoan e = new MemberToLoan();
		e.setMember(getAssociatedMember());
		e = EditorPanel.showEditorDialog(parent, "New", 
				MemberToLoan.class, e, this, this, this, forms);
		return e;
	}
	
	@Override
	public MemberToLoan open(Component component, MemberToLoan e) throws Throwable {
		
		e = BOLoan.create().refresh(e);
		
		List<AbstractEditorForm<MemberToLoan>> forms = new ArrayList<AbstractEditorForm<MemberToLoan>>();
		forms.add(new LoanGeneralForm());
		forms.add(new LoanHistoryForm());
		e = EditorPanel.showEditorDialog(component, "Edit", 
				MemberToLoan.class, e, this, this, this, forms);
		return e;
	}
	
	protected Member getAssociatedMember() {
		return null;
	}
	
	public static class ByMemberLoanHandler extends MemberToLoanHandler {
		private Member m;
		
		public ByMemberLoanHandler(Member m) {
			this.m = m;
		}
		
		@Override
		protected Member getAssociatedMember() {
			return m;
		}
		
		@Override
		public List<MemberToLoan> load() throws Throwable {
			if (m.getId() == null) {
				return m.getMemberToLoans();
			}
			List<MemberToLoan> loans = BOLoan.create().loadByMemberID(m.getId());
			m.setMemberToLoans(loans);
			return loans;
		}
		
	}
	
}
